<script lang="tsx">
/**
 * 基础单表格页面
 */
export default {
  name: "page-model"
}
</script>

<script lang="tsx" setup>
import {ref, defineProps, watch, nextTick} from "vue"
import {processRequest, XLSXExport} from "../../index.ts"
import {ElMessage, ElMessageBox} from "element-plus"

/**
 * 组件
 */
import PageModelManager from "./page-model-manager.ts"
import SearchForm from "../../components/business/search-form/index.vue"
import ProgramForm from "../../components/business/program-form/index.vue"
import TableForm from "../../components/business/table-form/index.vue"
import TableTabsForm from "./components/table-tabs-form/index.vue"
import Form from "../dialog-sheet-form/index.vue"
import SideSheetForm from "../side-sheet-form/index.vue";
import TableProgramForm from "./components/table-program-form/index.vue"

/**
 * 定义props
 */
const props = defineProps<{
  PageModel: PageModelManager<any>;
  reflections?: any;
}>()

/**
 * 基础单表格页面模型
 */
const pageModel = ref<PageModelManager<any>>()

/**
 * 监听
 */
watch(() => props.PageModel, function (newValue: any) {
  if (newValue) {
    pageModel.value = newValue
  }
}, {
  deep: true,
  immediate: true
})

/**
 * 组件实例
 */
const tableTabsFormRef = ref()
const searchFormRef = ref()
const programFormRef = ref()
const tableRef = ref()
const formRef = ref()
const sideFormRef = ref()

/**
 * 是否为编辑
 */
const isEdit = ref()

// region 内置事件

/**
 * 内置事件 -- 新增
 */
const handleAdd = (mode: "dialog" | "side" = "dialog") => {
  isEdit.value = false
  if (mode === "side") {
    sideFormRef.value.show()
    sideFormRef.value.initForm()
  } else {
    formRef.value.show()
    formRef.value.initForm()
  }
}

/**
 * 内置事件 -- 编辑
 */
const handleEdit = (row: any, mode: "dialog" | "side" = "dialog") => {
  isEdit.value = true
  if (mode === "side") {
    sideFormRef.value.show()
    nextTick(() => {
      sideFormRef.value.setFormData(row)
    })
  } else {
    formRef.value.show()
    nextTick(() => {
      formRef.value.setFormData(row)
    })
  }

}

/**
 * 内置事件 -- 删除
 */
const handleDelete = async (row: any) => {
  await ElMessageBox.confirm("是否确认删除？", "删除", {
    type: "error"
  })
  try {
    await processRequest.delete(pageModel.value?.deleteUrl || pageModel.value?.url as string, {
      id: row.id
    })
    ElMessage.success("删除成功")
    await refreshTableData()
  } catch (e) {
  } finally {
  }
}

// endregion

///region tabs栏事件

/**
 * tabs栏值改变
 */
const handleTabsFormChange = () => {
  refreshTableData()
}

//endregion

//region 搜索栏

/**
 * 获取搜索框数据
 */
const getSearchFormData = () => {
  return searchFormRef.value.getSearchFormData()
}

/**
 * 设置搜索框数据
 */
const setSearchFormData = (data: any) => {
  searchFormRef.value.setSearchFormData(data)
}

//endregion

//region 表格

/**
 * 获取表格所选项
 */
const getTableSelectData = () => {
  return tableRef.value.getSelectionData()
}

/**
 * 获取表格数据
 */
const getTableData = () => {
  return tableRef.value.getTableData()
}

/**
 * 设置表格数据
 */
const setTableData = (data: any[], total: number) => {
  if (pageModel.value?.getDataBack) {
    const list = pageModel.value?.getDataBack(data)
    tableRef.value.setTableData(list, total)
  } else {
    tableRef.value.setTableData(data, total)
  }
}

/**
 * 获取表单数据
 */
const getFormData = () => {
  return formRef.value.getFormData()
}

/**
 * 设置表单数据
 */
const setFormData = (data: any) => {
  formRef.value.setFormData(data)
}

/**
 * 监听表格提交
 */
const handleSubmit = async (params: any) => {
  if (!params) return false
  try {
    if (isEdit.value) {
      await processRequest.put(pageModel.value?.putUrl || pageModel.value?.url as string, {
        ...params
      })
    } else {
      await processRequest.post(pageModel.value?.postUrl || pageModel.value?.url as string, {
        ...params
      })
    }
    formRef.value.close()
    ElMessage.success(isEdit.value ? "编辑成功" : "新增成功")
    await refreshTableData()
  } catch (e) {
  } finally {
  }
}

/**
 * 刷新表格
 */
const refreshTableData = async () => {
  try {
    const otherParams = props.PageModel.otherParams
    const pageData = tableRef.value.getPaginationData()
    const tabsData = tableTabsFormRef.value?.getTabsFormData()
    const searchData = await searchFormRef.value?.getSearchFormData()
    const result: any = await processRequest.get(pageModel.value?.getUrl || pageModel.value?.url as string, {
      ...pageData,
      ...tabsData.value,
      ...searchData,
      ...otherParams
    })
    if (pageModel.value?.getProcessData) {
      const data = pageModel.value.getProcessData(result)
      setTableData(data.list, data.total)
    } else {
      setTableData(result.dataList, result.total)
    }
    ElMessage.success("刷新成功")
  } catch (e) {
  } finally {
  }
}

/**
 * 清空选中项
 */
const clearSelection = () => {
  tableRef.value.clearSelection()
}

/**
 * 导出
 */
const handleExport = async () => {
  const tableData = await tableRef.value.getTableData()
  XLSXExport(tableData, pageModel.value?.table.els)
}

/**
 * 表格配置
 */
const handleTableConfig = () => {

}

//endregion

/**
 * 暴露
 */
defineExpose({
  handleAdd,
  handleEdit,
  handleDelete,
  refreshTableData,
  getSearchFormData,
  setSearchFormData,
  getTableSelectData,
  getTableData,
  setTableData,
  getFormData,
  setFormData,
  handleExport,
  clearSelection
})
</script>

<template>
  <div class="content-logout">
    <div class="page-model">
      <div v-if="pageModel?.tabsForm" class="tabs-form">
        <slot name="tab-form">
          <TableTabsForm ref="tableTabsFormRef" :tabsFormModel="pageModel?.tabsForm" v-bind="$attrs"
                         @tabs-form-change="handleTabsFormChange"/>
        </slot>
      </div>
      <div v-if="pageModel?.searchForm" class="search-form">
        <slot name="search-form">
          <SearchForm ref="searchFormRef" :reflections="props?.reflections" :searchFormModel="pageModel?.searchForm"
                      v-bind="$attrs" @searchFormFilter="refreshTableData" @searchFormReset="refreshTableData"/>
        </slot>
      </div>
      <div v-if="pageModel?.programForm" class="program-form">
        <slot name="program-form">
          <ProgramForm ref="programFormRef" :programFormModel="pageModel?.programForm" v-bind="$attrs">
            <template #right>
              <TableProgramForm :extendButton="pageModel.extendButton" @export="handleExport"
                                @table-config="handleTableConfig"/>
            </template>
          </ProgramForm>
        </slot>
      </div>
      <div v-if="pageModel?.table" class="table">
        <slot name="table">
          <TableForm ref="tableRef" :getImmediate="pageModel.getImmediate!==false"
                     :tableModel="pageModel.table" v-bind="$attrs" @refreshTableData="refreshTableData">
          </TableForm>
        </slot>
      </div>
      <div v-if="pageModel?.form" class="form">
        <Form ref="formRef" :dialogSheetFormModel="pageModel.form" :reflections="props?.reflections"
              @submit="handleSubmit"/>
      </div>
      <div v-if="pageModel?.sideForm" class="side-form">
        <SideSheetForm ref="sideFormRef" :reflections="props?.reflections" :sideSheetFormModel="pageModel.sideForm"
                       v-bind="$attrs"
                       @submit="handleSubmit"/>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.content-logout {
  border-radius: 10px;
  padding: 20px;
  height: 100%;
  box-sizing: border-box;
  overflow: hidden;

  .page-model {
    height: 100%;
    display: flex;
    flex-direction: column;

    .tabs-form {
      flex: 0;
    }

    .search-form {
      flex: 0;
    }

    .program-form {
      flex: 0;
    }

    .table {
      flex: 1;
    }
  }
}
</style>